package cn.swunet.schat.service;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.util.Hashtable;
import java.util.Map;
import java.util.Vector;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;

import cn.swunet.bean.User;
import cn.swunet.dao.DBTools;


/**
 * 
 * @author: arosen.swunet@qq.com
 *
 * @date: 2020年4月12日
 *
 * @TDDO: SChat服务器  收到数据报--> 解析worker ----> SendWorker
 */
public class SchatMainServer {
	//data发送端口
	private int SendPort;
	//data接收端口
	private int RecvPort;
	//接收数据 socket
	private DatagramSocket RecvSocket;
	//缓冲区大小
	private int buffSize;
	//记录在线的用户
	public static Hashtable<Integer, Integer> onLineUserPoor;
	
	//线程池
	private ExecutorService ThreadPoor;

	//依据配置文件完成类构造
	SchatMainServer() {
		init();	
		
		//记录在线的用户
		onLineUserPoor = new Hashtable<Integer, Integer>();
		
		//使用 Executors，newFixedThreadPool任务队列无限制 容易OOM
		ThreadPoor = Executors.newFixedThreadPool(4);
	}
	

	/**
	 * 
	 * @author:arosen.swunet@qq.com
	 * @return:void
	 * @throws IOException 
	 * @TODO:
	 */
	public void start() throws IOException {
		
		//启动心跳检测线程
		UserManagerWorker uManager = new UserManagerWorker();
		Thread t_heartBeat = new Thread(uManager);
		t_heartBeat.start();
		
		//接收数据报
		while(true) {
			DatagramPacket packet = new DatagramPacket(new byte[buffSize], buffSize);
			RecvSocket.receive(packet);
			ThreadPoor.execute(new PacketHandlerWorker(packet));
		}
	}
	
	public static void main(String[] args) {
		try {
			new SchatMainServer().start();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 
	 * @author:arosen.swunet@qq.com
	 * @return:void
	 * @TODO:
	 */
	public void init() {
		//打开配置文件
		FileReader conf = null;
		try {
			conf = new FileReader("conf/schat.conf");
		} catch (FileNotFoundException e1) {
			System.out.println("schat.conf 打开失败");
		}
		
		//从文件完成服务器配置
		BufferedReader in = null;
        in = new BufferedReader(conf);
        String str  = null;
        String[] paramList;
        
        boolean isSuccess = true;
        
        //按行读取 进行配置
		try {
			while((str = in.readLine()) != null) {
				
				//读到注释行或错误配置行
				if (str.lastIndexOf("#") != -1 || str.lastIndexOf(":") == -1)
					continue;
				
				//分离配置名和参数
				paramList = str.split(":");
				
				//非法配置
				if (paramList.length < 1) {
					System.out.println("[" + str + "] 出错！");
					throw new IOException();
				}
				
				if (paramList[0].equals("port") && Integer.parseInt(paramList[1]) > 0 && 
						Integer.parseInt(paramList[1]) < 65535) {
					this.RecvPort = Integer.parseInt(paramList[1]);
				}else if (paramList[0].equals("buffSize") && Integer.parseInt(paramList[1]) > 0) {
					buffSize = Integer.parseInt(paramList[1]);
				}else
					continue;
			}
			
			//关闭
			in.close();
		} catch (IOException e) {
			System.out.println("读取schat.conf失败, 服务器初始化失败");
			isSuccess = false;
		}
		
		//配置出错
		if(!isSuccess) {
			System.out.println("服务器初始化失败");
			System.exit(0);
		}
		
		try {
			this.RecvSocket = new DatagramSocket(this.RecvPort);
		} catch (SocketException e) {
			System.out.println("服务器初始化失败");
			System.exit(0);
		}
	}
}
